package com.imflea.zero.service.wx.impl;

import cn.hutool.core.bean.BeanUtil;
import com.imflea.zero.constant.QxContant;
import com.imflea.zero.exception.BizException;
import com.imflea.zero.model.entity.qx.QxTenant;
import com.imflea.zero.model.entity.qx.QxTenantConfig;
import com.imflea.zero.model.entity.user.WebUserAccount;
import com.imflea.zero.model.entity.user.WebUserFarmyard;
import com.imflea.zero.model.entity.user.WebUserInfo;
import com.imflea.zero.model.entity.wx.vo.WxUserLoginVo;
import com.imflea.zero.service.qx.IQxTenantConfigService;
import com.imflea.zero.service.qx.IQxTenantService;
import com.imflea.zero.service.user.IWebUserAccountService;
import com.imflea.zero.service.user.IWebUserFarmyardService;
import com.imflea.zero.service.user.IWebUserInfoService;
import com.imflea.zero.service.wx.IWxAuthService;
import com.imflea.zero.util.ZeroCacheUtils;
import com.imflea.zero.util.ZeroJsonUtils;
import com.imflea.zero.util.base.CommonUtils;
import com.imflea.zero.utils.RandomNameUtils;
import com.imflea.zero.utils.SessionUtils;
import com.imflea.zero.utils.WxAuthUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 祥保玉
 * @PackageName: com.imflea.zero.service.impl
 * @ClassName: WxAuthServiceImpl
 * @Description
 * @date 2021-09-13  10:39:45
 */
@Service("wxAuthService")
@Slf4j
public class WxAuthServiceImpl implements IWxAuthService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private IQxTenantService qxTenantService;
    @Autowired
    private IWebUserInfoService webUserInfoService;
    @Autowired
    private IQxTenantConfigService tenantConfigService;
    @Autowired
    private IWebUserFarmyardService webUserFarmyardService;
    @Autowired
    private IWebUserAccountService webUserAccountService;


    @Override
    public WxUserLoginVo saveOrLogin4WxAuth(String code) {
        String tenantId = SessionUtils.getTenantId();
        QxTenant tenant = qxTenantService.getById(tenantId);
        if (CommonUtils.isNull(tenant)) {
            throw new BizException("未匹配到对应的商户，请确认商户是否正常运营");
        }
        QxTenantConfig config = tenantConfigService.queryByTenantId(tenantId);
        if (CommonUtils.isNull(config)) {
            throw new BizException("请补充小程序配置信息");
        }
        String wxAppId = config.getWxAppId();
        String wxSecrt = config.getWxSecret();
        try {
            Map<String, String> wxAuthInfo = WxAuthUtils.getOpenId(code, wxAppId, wxSecrt);
            String openId = wxAuthInfo.get("openId");
            if (CommonUtils.isNull(openId)) {
                throw new BizException("用户授权失败,未获取openId");
            }
            WebUserInfo userInfo = webUserInfoService.queryByOpenId(openId);
            String sessionKey = wxAuthInfo.get("sessionKey");


            //系统不存在该用户，进行注册，新增操作
            if (CommonUtils.isNull(userInfo)) {
                String unionId = wxAuthInfo.get("unionId");
                // 放入到缓存中
                String id = CommonUtils.generateRandomString();
                userInfo = new WebUserInfo();
                userInfo.setId(id);
                String randomName = RandomNameUtils.randomName(false, 4);
                String randomFav = RandomNameUtils.generateImg(randomName);

//                userInfo.setCreateTime(LocalDateTime.now());
                userInfo.setNickName(randomName);
                userInfo.setAvatarUrl(randomFav);
                userInfo.setOpenId(openId);
                userInfo.setUnionId(unionId);
                logger.error("userInfo:" + ZeroJsonUtils.entityToJson(userInfo));
                boolean success = webUserInfoService.updateWebUserInfo(userInfo);
//
                WebUserFarmyard farmyard = new WebUserFarmyard();
                farmyard.setFarmName("我的农场");
                farmyard.setWebUserId(id);
                webUserFarmyardService.saveOrUpdateWebUserFarmyard(farmyard);

                WebUserAccount account = new WebUserAccount();
                account.setUserId(userInfo.getId());
                account.setUserAccount(new BigDecimal(BigInteger.ZERO));
                webUserAccountService.saveOrUpdateWebUserAccount(account);
                if (!success) {
                    throw new BizException("用户授权失败");
                }
            }
            String wxNickName = userInfo.getNickName();
            String accessToken = this.logInUtils(userInfo.getId(), openId, tenantId, wxNickName, userInfo.getAvatarUrl());

            ZeroCacheUtils.setString(QxContant.getWxLoginSessionKeyPrefix() + tenantId + userInfo.getId(), sessionKey);
            WxUserLoginVo vo = new WxUserLoginVo();
            BeanUtil.copyProperties(userInfo, vo);
            vo.setAccessToken(accessToken);
            return vo;
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        }
    }

    @Override
    public WebUserInfo updateUserDetailInfo(String code, String encryptedData, String iv) {
        String tenantId = SessionUtils.getTenantId();
        QxTenant tenant = qxTenantService.getById(tenantId);
//

        QxTenantConfig config = tenantConfigService.queryByTenantId(tenantId);
//        String wxAppId = "wx510e2c6457f4b25c";
//        String wxSecrt = "18034c6dd7485f0eb4a6c7a36be1c3df";
        String wxAppId = config.getWxAppId();
        String wxSecrt = config.getWxSecret();
        //从头信息或者登录信息中获取
        String openId = SessionUtils.getOpenId();
        String sessionKey = null;
        String userId = SessionUtils.getUserId();
        try {
            sessionKey = WxAuthUtils.getSessionKey(code, wxAppId, wxSecrt);
        } catch (Exception e) {
            throw new BizException("获取sessionKey异常" + e.getMessage());
        }
        WebUserInfo userInfo = webUserInfoService.queryByOpenId(openId);
        if (CommonUtils.isNull(userInfo)) {
            throw new BizException("当前用户异常");
        } else {
            try {
                Map<String, Object> wxUserDetailMap = WxAuthUtils.getUserDetailInfo(wxAppId, wxSecrt, openId, encryptedData, sessionKey, iv);
//                String enOpenId = (String) wxUserDetailMap.get("openId");
//                if (CommonUtils.isNull(enOpenId)) {
//                    throw new BizException("解析openId为空");
//                }
//                if (!openId.equals(enOpenId)) {
//                    throw new BizException("解析openId与当前用户openId不符");
//                }
//
//                String nickName = (String) wxUserDetailMap.get("nickName");
//                userInfo.setNickName(nickName);
//                String gender = (String) wxUserDetailMap.get("gender");
//                userInfo.setGender(gender);
//                String city = (String) wxUserDetailMap.get("city");
//                userInfo.setCity(city);
//                String province = (String) wxUserDetailMap.get("province");
//                userInfo.setProvince(province);
//                String country = (String) wxUserDetailMap.get("country");
//                userInfo.setCountry(country);
//                String avatarUrl = (String) wxUserDetailMap.get("avatarUrl");
//                userInfo.setAvatarUrl(avatarUrl);
                String phoneNumber = (String) wxUserDetailMap.get("phoneNumber");
                userInfo.setCellNum(phoneNumber);
                boolean isSuccess = this.webUserInfoService.updateById(userInfo);
                if (isSuccess) {
                    return userInfo;
                } else {
                    throw new BizException("获取手机等详细信息失败");
                }
            } catch (Exception e) {
                throw new BizException(e.getMessage());
            }
        }
    }

    private String logInUtils(String userId, String openId, String tenantId, String nickName, String avatarUrl) throws Exception {
        //缓存中存储：认证信息，user信息，id  openId，tenantId
        Map<String, Object> loginedInfo = new HashMap<>();
        loginedInfo.put("userId", userId);
        loginedInfo.put("tenantId", tenantId);
        loginedInfo.put("openId", openId);
        loginedInfo.put("wxNickName", nickName);
        loginedInfo.put("avatarUrl", avatarUrl);


        String accessTokenKey = CommonUtils.generateRandomString();
        String accessTokenIndb = QxContant.getWxLoginAccessTokenKey() + tenantId + ":" + accessTokenKey;
        loginedInfo.put("accessToken", accessTokenKey);

        String token = ZeroJsonUtils.mapToJson(loginedInfo);

        ZeroCacheUtils.setString(accessTokenIndb, token);
        ZeroCacheUtils.expire(accessTokenIndb, QxContant.getWxSessionTime());

        return accessTokenKey;
    }

    public boolean refreshlogInUtils(String accessToken, String tenantId, String nickName, String avatarUrl) throws Exception {
        //缓存中存储：认证信息，user信息，id  openId，tenantId
        String accessTokenIndb = ZeroCacheUtils.getString(QxContant.getWxLoginAccessTokenKey() + tenantId + ":" + accessToken);

        if (!CommonUtils.isNull(accessTokenIndb)) {
            Map<String, Object> loginedInfo = ZeroJsonUtils.jsonToMap(accessTokenIndb);
            loginedInfo.put("wxNickName", nickName);
            loginedInfo.put("avatarUrl", avatarUrl);
            ZeroCacheUtils.setString(QxContant.getWxLoginAccessTokenKey() + tenantId + ":" + accessToken, ZeroJsonUtils.mapToJson(loginedInfo));
            ZeroCacheUtils.expire(accessTokenIndb, QxContant.getWxSessionTime());
        } else {
            return false;
        }
        return true;
    }


}
